------------------------------------------------------------------------------------------------------------------------------------------------
-- -- tasks base lib


-------------------------------------------------------------------------------------------------------------------------------------------------

local function NPC_TASKS_INIT(inst)
    local theNPC = inst.entity:GetParent()
    if not theNPC:HasTag("player") then --------------------------
        theNPC:AddTag("INLIMBO")
        theNPC:AddTag("notarget")
        theNPC:AddTag("noattack")
        theNPC:AddTag("invisible")
        theNPC:AddTag("Unable_To_Refuse")
        theNPC.npc_event = inst.prefab
    else----------------------------------------- 如果是玩家
        -- theNPC is player
        -- TheNet:Anounce( " ++++++++++++")
        -- if theNPC.components.npc_base_lib:Get_Language() == "ch" then
        --     theNPC.components.npc_base_lib:Announce("一个特殊的海狸雕像出现，可以召唤海狸伍迪帮忙")
        -- else
        --     theNPC.components.npc_base_lib:Announce("A special beaver statue appears and can summon Woodie the beaver to help")
        -- end

        theNPC.components.inventory:GiveItem(SpawnPrefab("npc_item_woodie_beaver_wereitem"))
        theNPC:SpawnChild("npc_fx_spawn")
        inst:Remove()
    end
end
-------------------------------------------------------------------------------------------------------------------------------------------------

local function Check_Around_Tree(theNPC,ItemInst)
    local flag,tree = pcall(function()
        local working_range = theNPC.working_range or 15

        local x,y,z = ItemInst.Transform:GetWorldPosition()    
        local musthavetags = {"tree","plant"}
        local canthavetags = {"INLIMBO","npc_tag_tree_ban"}
        local musthaveoneoftags = nil
        local ban_prefab_list = {
            ["livingtree"] = true,
            ["livingtree_halloween"] = true
        }
        local temp_trees_table = {}
        local ents = TheSim:FindEntities(x, 0, z, working_range, musthavetags, canthavetags, musthaveoneoftags)
        for k, tempTree in pairs(ents) do
            if tempTree and tempTree:IsValid() then
                if tempTree.components.workable and ( tempTree.components.workable.action == ACTIONS.CHOP or tempTree.components.workable.action == ACTIONS.DIG )
                and tempTree.components.lootdropper             
                then
                    -- return tempTree
                    table.insert(temp_trees_table, tempTree)
                end
            end
        end

        if #temp_trees_table > 0 then
            local nearest_tree = temp_trees_table[1]
            local nearest_distance = theNPC.npc_base_lib:Distance_Targets(nearest_tree,theNPC)
            for k, tempTree in pairs(temp_trees_table) do
                local distance = theNPC.npc_base_lib:Distance_Targets(theNPC,tempTree)
                if distance < nearest_distance then
                    nearest_distance = distance
                    nearest_tree = tempTree
                end
            end

            if nearest_tree then
                return nearest_tree
            end
        end

        return nil

    end)
    if flag == false then
        print("Error : ")
        print(tree)
    end

    if flag == false or tree == nil then
        return nil
    else
        return tree
    end
end

local function Close_2_Tree_fn(theNPC)
    theNPC.event_step = 2

    local tar_tree = theNPC.Target_Tree
    local tar_fase_point = Vector3(tar_tree.Transform:GetWorldPosition())
    theNPC.npc_base_lib:Stop()
    theNPC.npc_base_lib:FaceToPoint(tar_fase_point)
    theNPC:DoTaskInTime(0.2,function()
        theNPC.AnimState:PlayAnimation("atk_pre")
        theNPC.AnimState:PushAnimation("atk", false)
        theNPC.AnimState:PushAnimation("idle_loop",false)
        -- theNPC.SoundEmitter:PlaySound("dontstarve/wilson/attack_whoosh")
        if tar_tree.SoundEmitter then            
            tar_tree.SoundEmitter:PlaySound("dontstarve/wilson/use_axe_tree")
        end
        theNPC:DoTaskInTime(0.3,function()
            local crash_flag = pcall(function()
                tar_tree.components.lootdropper:DropLoot()
                tar_tree.components.lootdropper:DropLoot()
                tar_tree:Remove()
                theNPC.event_step = nil 
                if theNPC.wereitem then
                    theNPC.wereitem:PushEvent("USE")
                end
            end)

            if crash_flag == false then ----------- 发生崩溃
                tar_tree:AddTag("npc_tag_tree_ban")
                theNPC.event_step = nil
            else
                theNPC.Target_Tree = nil
                theNPC.event_step = nil
            end

        end)
        -- local function Attack_Anim_End(theNPC)
        --     theNPC:RemoveEventCallback("animqueueover",Attack_Anim_End)
        --     -- theNPC.AnimState:PlayAnimation("idle_loop")
    
        --     tar_tree:Remove()
    
        --     theNPC:DoTaskInTime(0.4,function ()
        --         theNPC.event_step = nil            
        --     end)
        --     -- theNPC.event_step = nil            
    
        -- end
        -- theNPC:ListenForEvent("animqueueover",Attack_Anim_End)


    end)

end


local function NPC_TASKS(inst)
    local theNPC = inst.entity:GetParent()

    if theNPC:HasTag("player") then
        return
    end

    if TheWorld.state.isnight  or TheWorld:HasTag("cave") then
        theNPC.npc_base_lib:Try_2_Set_Light(true)
    else
        theNPC.npc_base_lib:Try_2_Set_Light(false)
    end
    
    if theNPC.wereitem == nil then
        theNPC:Remove()
        return
    end
    local BasePoint_Item = theNPC.wereitem
    local working_range = theNPC.working_range or 15

    if theNPC.event_step == nil then
        theNPC.Target_Tree = Check_Around_Tree(theNPC,BasePoint_Item)
        if theNPC.Target_Tree == nil then
            theNPC.npc_base_lib:Run_Around_Target_In_Range({
                target = BasePoint_Item,
                range = working_range,
                random_range_flag = true,
                mid_reflash_range = 2
            })            
        else
            theNPC.event_step = 1
        end
    elseif theNPC.event_step == 1 then
        theNPC.npc_base_lib:Close_2_Target_In_Range({
            target = theNPC.Target_Tree,
            range = 3,
            fn = Close_2_Tree_fn,
        })   

        if theNPC.Target_Tree and not theNPC.Target_Tree:IsValid() then
            theNPC.Target_Tree = nil
            theNPC.event_step = nil
        end 
            
    elseif theNPC.event_step == 2 then
        ---- 空的，等待 Close_2_Tree_fn 修改 event_step
        ----
        
    end

end
--------------------------------------------------------------------------------------------------------------------------------------------------

local function OnAttached(inst,target) -- when the debuff on or player is newSpawn(or through the cave)
    inst.entity:SetParent(target.entity)
    inst.Network:SetClassifiedTarget(target)
    local NPC = inst.entity:GetParent()
    local flag ,error_code= pcall(function(inst,target)
        if TheWorld.ismastersim then

            NPC_TASKS_INIT(inst)


        end
    end,inst,target)
    if flag == false  then
        print("Error : OnAttached(inst,target) ",inst.prefab)
        print(error_code)
        NPC:Remove()
    end
end

local function OnDetached(inst) -- When eliminating from the outside
    local player = inst.entity:GetParent()   
    -- print(" FROM OUSIDE REMOVE ")
    
    -- inst:Remove()
end

local function ExtendDebuff(inst)
    -- inst.countdown = 3 + (inst._level:value() < CONTROL_LEVEL and EXTEND_TICKS or math.floor(TUNING.STALKER_MINDCONTROL_DURATION / FRAMES + .5))
end



local function OnUpdate(inst,ismastersim)
    local NPC = inst.entity:GetParent()
    local flag,error_code = pcall(function(inst,ismastersim)
        -- local NPC = inst.entity:GetParent()

        NPC_TASKS(inst)


    end,inst,ismastersim)
    if flag == false then
        print("Error : OnUpdate(inst,ismastersim) ,step:",NPC.event_step ,inst.prefab)
        print(error_code)
        NPC:Remove()
    end
end

local function fn()
    local inst = CreateEntity()

    inst.entity:AddTransform()
    inst.entity:AddNetwork()

    inst:AddTag("CLASSIFIED")


    -- inst:DoPeriodicTask(1, OnUpdate, nil, TheWorld.ismastersim)  -- in one seconds
    inst:DoPeriodicTask( 0.5, OnUpdate, nil, TheWorld.ismastersim)  -- in 0.5 seconds

    inst.entity:SetPristine()

    if not TheWorld.ismastersim then
        return inst
    end

    inst:AddComponent("debuff")
    inst.components.debuff:SetAttachedFn(OnAttached)
    inst.components.debuff.keepondespawn = false -- 是否保持debuff 到下次登陆
    -- inst.components.debuff:SetDetachedFn(inst.Remove)
    inst.components.debuff:SetDetachedFn(OnDetached)
    -- inst.components.debuff:SetExtendedFn(ExtendDebuff)
    -- ExtendDebuff(inst)


    return inst
end

return Prefab("npc_event_woodie_beaver", fn)
